<template>
    <a-form ref="formRef" :model="form" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol">
        <a-form-item v-for="item in formConfig" :key="item.prop" :label="item.label" :name="item.prop">
            <template v-if="item.custom === 'upload'">                
                <img v-if="item.disabled" :src="imageUrl" alt="avatar" class="upload-image" />
                <a-upload v-else v-model:file-list="fileList" name="avatar" list-type="picture-card" class="avatar-uploader top"
                    :show-upload-list="false" action="https://mgapi.fediot.net/api/system/upload" :headers="myheader"
                    :before-upload="beforeUpload" @change="handleChange">
                    <img v-if="imageUrl" :src="imageUrl" alt="avatar" class="upload-image" />
                    <div v-else>
                        <loading-outlined v-if="loading"></loading-outlined>
                        <plus-outlined v-else></plus-outlined>
                        <div class="ant-upload-text">Upload</div>
                    </div>
                </a-upload>
            </template>
            <template v-else-if="item.custom === 'input'">
                <a-input :disabled="item.disabled" v-model:value="form[item.prop]" :placeholder="item.placeholder"
                    :show-password="item.password">
                </a-input>
                <slot :name="item.prop"></slot>  
            </template>
            <template v-else-if="item.custom === 'passwordIpt'">
                <a-input-password :disabled="item.disabled" v-model:value="form[item.prop]" :placeholder="item.placeholder" />               
                <slot :name="item.prop"></slot>  
            </template>
            <template v-else-if="item.custom === 'select'">
                <a-select :disabled="item.disabled" v-model:value="form[item.prop]" :placeholder="item.placeholder">
                    <a-select-option v-for="option in item.options" :key="option.value" :value="option.value"> {{
                        option.label }}
                    </a-select-option>
                </a-select>
            </template>
            <template v-else-if="item.custom === 'cascader'">
                <a-cascader :disabled="item.disabled" :options="item.options" v-model:value="form[item.prop]" :placeholder="item.placeholder" />
            </template>
            <template v-else-if="item.custom === 'picker'">
                <a-date-picker :disabled="item.disabled" v-model:value="form[item.prop]" :placeholder="item.placeholder" style="width: 100%;" />
            </template>
        </a-form-item>

    </a-form>
</template>

<script setup>
import { reactive, ref } from 'vue';
import { message } from 'ant-design-vue';
function getBase64(img, callback) {
  const reader = new FileReader();
  reader.addEventListener('load', () => callback(reader.result));
  reader.readAsDataURL(img);
}
const fileList = ref([]);
const loading = ref(false);
const imageUrl = ref('https://qiniu.qhdkhkj.com/head/e68a7af57d19b4cb50ba46a7b7f9553a_657a9d18677ad.png');
const myheader = {
  Authorization: 'Bearer '
}
const handleChange = info => {
  if (info.file.status === 'uploading') {
    loading.value = true;
    return;
  }
  if (info.file.status === 'done') {
    // Get this url from response in real world.
    getBase64(info.file.originFileObj, base64Url => {
      imageUrl.value = base64Url;
      loading.value = false;
    });
  }
  if (info.file.status === 'error') {
    loading.value = false;
    message.error('upload error');
  }
};
const beforeUpload = file => {
  const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
  if (!isJpgOrPng) {
    message.error('You can only upload JPG file!');
  }
  const isLt2M = file.size / 1024 / 1024 < 2;
  if (!isLt2M) {
    message.error('Image must smaller than 2MB!');
  }
  return isJpgOrPng && isLt2M;
};


const props = defineProps({
    formConfig: {
        type: Array,
        default: () => []
    },
})
const form = reactive({}) // 表单数据
const rules = {} // 表单校验
props.formConfig.forEach(item => {
    if (!item.rule) return
    rules[item.prop] = item.rule
})

const labelCol = {
    span: 5,
};
const wrapperCol = {
    span: 13,
};

defineExpose({
    form
})
</script>

<style lang="scss" scoped>
.avatar-uploader > .ant-upload {
  width: 116px;
  height: 116px;
}
.upload-image{
    display: inline-block;
    width: 116px;
    height: 116px;
}

.top{
    margin: 7px 0 5px 7px;
}
.ant-upload-select-picture-card i {
  font-size: 32px;
  color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
  margin-top: 8px;
  color: #666;
}
::v-deep .ant-form-item-control-input-content {
  display: flex;
}
</style>